package com.sgzn.sgpay.service.impl;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.sgzn.sgpay.enums.SeqFlagEnum;
import com.sgzn.sgpay.enums.SgsResponseCode;
import com.sgzn.sgpay.model.request.SgsMchLoginRequest;
import com.sgzn.sgpay.model.request.SgsMchQuitRequest;
import com.sgzn.sgpay.model.request.SgsMchValidTokenRequest;
import com.sgzn.sgpay.model.request.SgsPrivQueryRequest;
import com.sgzn.sgpay.model.response.SgsResultResponse;
import com.sgzn.sgpay.model.response.result.MchLoginResult;
import com.sgzn.sgpay.persistence.dao.TMchLoginSessionMapper;
import com.sgzn.sgpay.persistence.dao.TMerchantMapper;
import com.sgzn.sgpay.persistence.domain.*;
import com.sgzn.sgpay.service.SgsMchLoginService;
import com.sgzn.sgpay.service.SgsPrivQueryService;
import com.sgzn.sgpay.service.support.SgsResponseUtil;
import com.sgzn.sgpay.util.SeqUtil;
import com.sgzn.sgpay.util.TranslateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 商户登录接口
 * @author zhongzhongyong
 * @version Id: SgsMchLoginServiceImpl.java, v 0.1 2018/5/11 23:42 zhongzhongyong Exp $$
 */
@Service
@Slf4j
public class SgsMchLoginServiceImpl implements SgsMchLoginService {

    @Resource
    private TMerchantMapper tMerchantMapper;

    @Resource
    private TMchLoginSessionMapper tMchLoginSessionMapper;

    @Resource
    private SgsPrivQueryService sgsPrivQueryService;

    /**
     * 有效时间：两个小时，7200000毫秒
     */
    private static long VALID_MS = 7200000;

    /**
     * 登录逻辑：
     * 1.根据商户账户查询商户信息，若存在则比对登录密码是否正确，
     * 2.若信息无误，则按照手机号和随机生成的token更新商户登录会话表（一个商户手机号只能保存一条会话数据）
     * @param request
     * @return
     */
    @Override
    public SgsResultResponse<MchLoginResult> login(SgsMchLoginRequest request) {
        try{
            TMerchant tMerchant = this.getMerchant(request);
            //校验账号是否存在
            if(tMerchant == null){
                return SgsResponseUtil.INSTANCE.fail(SgsResponseCode.C_MCH_NOT_FOUND.getResponseCode(),
                        SgsResponseCode.C_MCH_NOT_FOUND.getResponseDesc());
            }
            //校验密码是否正确
            if(!tMerchant.getPassword().equals(request.getPassword().trim())){
                return SgsResponseUtil.INSTANCE.fail(SgsResponseCode.C_MCH_PWD_ERROR.getResponseCode(),
                        SgsResponseCode.C_MCH_PWD_ERROR.getResponseDesc());
            }
            //生成随机token
            String token = SeqUtil.getShortSeq(SeqFlagEnum.TOKEN.getCode());
            this.tMchLoginSessionLog(tMerchant.getMerchantId(),request.getLoginAccount(),token);
            //获取权限集合
            List<String> privList = getPrivList(tMerchant.getMerchantId(),request);
            //组装结果
            MchLoginResult result = new MchLoginResult();
            result.setToken(token);
            result.setPrivList(privList);
            return SgsResponseUtil.INSTANCE.success(result);
        }catch (Exception e){
            log.error("[{}]. 插入响应流水日志异常.", request.getInitiationID(),e);
            return SgsResponseUtil.INSTANCE.fail(SgsResponseCode.C_DB_EXCEPTION.getResponseCode(),
                    SgsResponseCode.C_DB_EXCEPTION.getResponseDesc());
        }
    }


    /**
     * 退出
     * @param request
     * @return
     */
    @Override
    public SgsResultResponse<String> quit(SgsMchQuitRequest request) {
        TMchLoginSession session = new TMchLoginSession();
        session.setToken("");//token置为空
        session.setUpdatedAt(new Date());
        tMchLoginSessionMapper.updateByPrimaryKey(session);
        return SgsResponseUtil.INSTANCE.success("1");//退出成功
    }

    /**
     * 获取商户信息
     * @param request
     * @return
     */
    private TMerchant getMerchant(SgsMchLoginRequest request){
        //查询商户基础信息
        TMerchantExample tMerchantExample = new TMerchantExample();
        TMerchantExample.Criteria tMchCrit = tMerchantExample.createCriteria();
        tMchCrit.andContactEqualTo(request.getLoginAccount());
        List<TMerchant> tMerchantList = tMerchantMapper.selectByExample(tMerchantExample);
        TMerchant tMerchant = null;
        if(CollectionUtils.isNotEmpty(tMerchantList)){
            tMerchant = tMerchantList.get(0);
        }
        return tMerchant;
    }

    /**
     * 判断token是否有效
     * @param session
     * @return
     */
    private boolean tokenIsValid(TMchLoginSession session){
        boolean result = false;
        long before = session.getUpdatedAt().getTime();
        long current = System.currentTimeMillis();
        long ms = current - before;
        if(ms <= VALID_MS){
            result = true;
        }
        return result;
    }

    /**
     * 商户登录会话表记录
     * @param mchId
     * @param mobileNo
     * @param token
     */
    private void tMchLoginSessionLog( String mchId, String mobileNo, String token){
        //根据mchId和mobileNo查找登录会话表是否存在记录
        TMchLoginSessionExample queryExample = new TMchLoginSessionExample();
        TMchLoginSessionExample.Criteria criteria = queryExample.createCriteria();
        criteria.andMchIdEqualTo(mchId);
        criteria.andMobilenoEqualTo(mobileNo);
        List<TMchLoginSession> sList = tMchLoginSessionMapper.selectByExample(queryExample);
        if(sList != null && sList.size()>0){
            //已存在登录历史记录
            Integer hisId = sList.get(0).getId();
            TMchLoginSession updateSession = new TMchLoginSession();
            updateSession.setId(hisId);
            updateSession.setToken(token);
            updateSession.setUpdatedAt(new Date());
            log.info("已存在登录历史记录,updateSession:{}",updateSession);
            tMchLoginSessionMapper.updateByPrimaryKeySelective(updateSession);
        }else{
            TMchLoginSession tMchLoginSession = new TMchLoginSession();
            tMchLoginSession.setMobileno(mobileNo);
            tMchLoginSession.setMchId(mchId);
            tMchLoginSession.setToken(token);
            tMchLoginSession.setCreatedAt(new Date());
            tMchLoginSession.setUpdatedAt(new Date());
            try{
                tMchLoginSessionMapper.insertSelective(tMchLoginSession);
            }catch (DataAccessException e) {
                log.error("[{}]. 插入响应流水日志异常.{}",e.getStackTrace());
            }
        }
    }

    /**
     * 获取权限列表
     * @param mchId
     * @param request
     * @return
     */
    private List<String> getPrivList(String mchId,SgsMchLoginRequest request){
        List<String> resultList = new ArrayList<>();
        SgsPrivQueryRequest target = new SgsPrivQueryRequest();
        target.setInitiationID(request.getInitiationID());
        target.setLoginChannel(request.getLoginChannel());
        target.setMchId(mchId);
        target.setReqTime(request.getReqTime());
        SgsResultResponse<List<TPrivilege>> privResp = this.sgsPrivQueryService.queryPrivByMchId(target);
        if(TranslateUtil.isSuccessAbs(privResp.getErrorCode()) && CollectionUtils.isNotEmpty(privResp.getResult())){
            List<TPrivilege> privilegeList = privResp.getResult();
            for(TPrivilege item: privilegeList){
                resultList.add(item.getPrivId());
            }
        }
        return resultList;
    }
}
